﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Timers;
using System.Windows.Threading;

namespace UI

{
    public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
    {
        private bool isFreezed = false;
      
        private readonly DispatcherTimer dispTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 1) };
        public bool Freezed 
        { 
            get { return isFreezed; }
            set 
    
            {
                isFreezed = value;
                OnPropertyChanged(()=>Freezed);
            }
        }
        protected ViewModelBase() 
        {
            
            dispTimer.Tick += dispTimer_Tick; 
            
            dispTimer.Start();
        }

        void dispTimer_Tick(object sender, EventArgs e)
        {
            if (isFreezed == true) return;
            UpdateProperties();
        }

        protected abstract void UpdateProperties();

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Get name of property
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="e"></param>
        /// <returns></returns>
        public static string GetPropertyName<T>(Expression<Func<T>> e)
        {
            var member = (MemberExpression)e.Body;
            return member.Member.Name;
        }

        /// <summary>
        /// Raise when property value propertyChanged
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="propertyExpression"></param>
        protected virtual void OnPropertyChanged<T>(Expression<Func<T>> propertyExpression)
        {
            OnPropertyChanged(GetPropertyName(propertyExpression));
        }

        /// <summary>
        /// Raise when property value propertyChanged 
        /// </summary>
        /// <param name="propertyName"></param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler.Invoke(this, e);
            }
        }

        public void Dispose()
        {
            dispTimer.Stop();
            this.OnDispose();
        }

        protected virtual void OnDispose(){}
    }
}
